package Sintactico;

import java.util.ArrayList;
import java.util.List;
import Lexico.CatLexica;
import Lexico.Token;
import MaquinaVirtual.Insts;
import Sintactico.TS.Propiedad;
import Tipos.Tipo;
import Tipos.TipoNumerico;
import Tipos.TipoProcedimiento;

public class TinyGA {
	public TinyGA() {
	}
	
	public enum Clase {
		var, pvar, proc
	};
	
	public enum Modo {
		var, valor
	};

	abstract public class Programa {
		protected Programa() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
		}

		// Atributos
		public Atributo<Error> error() {
			return error;
		}

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract Error error_exp();

		protected abstract ArrayList<Insts> cod_exp();

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
	}

	// DECLARACIONES

	abstract public class Declaraciones {

		protected Declaraciones() {

			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});

			dir = new Atributo<Integer>();
			dir.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return dir_exp();
				}
			});

			ts = new Atributo<TS>();
			ts.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ts_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			anidamiento = new Atributo<Integer>();
			anidamiento.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return anidamiento_exp();
				}
			});

			nivelh = new Atributo<Integer>();
			nivelh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.nivelh_exp();
				}
			});
			dirh = new Atributo<Integer>();
			dirh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.dirh_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});

		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}
		protected abstract ArrayList<Insts> cod_exp();
		
		public Atributo<Integer> dir() {
			return dir;
		}

		protected abstract Integer dir_exp();

		public Atributo<TS> ts() {
			return ts;
		}

		protected abstract TS ts_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Integer> anidamiento() {
			return anidamiento;
		}

		protected abstract Integer anidamiento_exp();

		public Atributo<Integer> dirh() {
			return dirh;
		}

		public Atributo<Integer> nivelh() {
			return nivelh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		public void registraCtx(DeclaracionesCtx ctx) {
			this.ctx = ctx;
		}

		private DeclaracionesCtx ctx;

		private Atributo<Error> error;
		private Atributo<Integer> dir;
		private Atributo<TS> ts;
		private Atributo<Integer> etq;
		private Atributo<Integer> anidamiento;
		private Atributo<Integer> dirh;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
		private Atributo<Integer> nivelh;
		private Atributo<ArrayList<Insts>> cod;

	}

	public interface DeclaracionesCtx {
		public TS tsh_exp();

		public Integer dirh_exp();

		public Integer nivelh_exp();

		public Integer etqh_exp();
	}

	// LISTADECLARACIONES
	abstract public class ListaDeclaraciones {
		protected ListaDeclaraciones() {

			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});

			dir = new Atributo<Integer>();
			dir.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return dir_exp();
				}
			});

			ts = new Atributo<TS>();
			ts.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ts_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});

			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});

			anidamiento = new Atributo<Integer>();
			anidamiento.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return anidamiento_exp();
				}
			});

			// Heredados
			nivelh = new Atributo<Integer>();
			nivelh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.nivelh_exp();
				}
			});
			dirh = new Atributo<Integer>();
			dirh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.dirh_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});

			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});

		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<Integer> dir() {
			return dir;
		}

		protected abstract Integer dir_exp();

		public Atributo<TS> ts() {
			return ts;
		}

		protected abstract TS ts_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Integer> anidamiento() {
			return anidamiento;
		}

		protected abstract Integer anidamiento_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> dirh() {
			return dirh;
		}

		public Atributo<Integer> nivelh() {
			return nivelh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		public void registraCtx(ListaDeclaracionesCtx ctx) {
			this.ctx = ctx;
		}

		private ListaDeclaracionesCtx ctx;

		private Atributo<Error> error;
		private Atributo<Integer> dir;
		private Atributo<TS> ts;
		private Atributo<Integer> etq;
		private Atributo<Integer> anidamiento;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> dirh;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
		private Atributo<Integer> nivelh;

	}

	public interface ListaDeclaracionesCtx {
		public TS tsh_exp();

		public Integer dirh_exp();

		public Integer nivelh_exp();

		public Integer etqh_exp();
	}

	// DECLARACION
	abstract public class Declaracion {
		protected Declaracion() {

			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});

			dir = new Atributo<Integer>();
			dir.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return dir_exp();
				}
			});

			clase = new Atributo<Clase>();
			clase.fijaExpresion(new ExpSem<Clase>() {
				public Clase val() {
					return clase_exp();
				}
			});

			// ¿De que tipo es?
			tipo = new Atributo<Tipo>();
			tipo.fijaExpresion(new ExpSem<Tipo>() {
				public Tipo val() {
					return tipo_exp();
				}
			});

			tam = new Atributo<Integer>();
			tam.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return tam_exp();
				}
			});
			
		
			iden = new Atributo<String>();
			iden.fijaExpresion(new ExpSem<String>() {
				public String val() {
					return iden_exp();
				}
			});

			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});

			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});

			anidamiento = new Atributo<Integer>();
			anidamiento.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return anidamiento_exp();
				}
			});

			// Heredados

			dirh = new Atributo<Integer>();
			dirh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.dirh_exp();
				}
			});

			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
			
			nivelh = new Atributo<Integer>();
			nivelh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.nivelh_exp();
				}
			});

			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<Integer> dir() {
			return dir;
		}

		protected abstract Integer dir_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Integer> anidamiento() {
			return anidamiento;
		}

		protected abstract Integer anidamiento_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Clase> clase() {
			return clase;
		}

		protected abstract Clase clase_exp();

		public Atributo<Tipo> tipo() {
			return tipo;
		}

		protected abstract Tipo tipo_exp();

		public Atributo<Integer> tam() {
			return tam;
		}

		protected abstract Integer tam_exp();

		public Atributo<String> iden() {
			return iden;
		}

		protected abstract String iden_exp();

		// Heredados
		public Atributo<Integer> dirh() {
			return dirh;
		}

		public Atributo<Integer> nivelh() {
			return nivelh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(DeclaracionCtx ctx) {
			this.ctx = ctx;
		}

		private DeclaracionCtx ctx;

		private Atributo<Error> error;
		private Atributo<Integer> dir;
		private Atributo<Integer> etq;
		private Atributo<Integer> anidamiento;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Clase> clase;
		private Atributo<Tipo> tipo;
		private Atributo<Integer> tam;
		private Atributo<String> iden;
		private Atributo<Integer> dirh;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
		private Atributo<Integer> nivelh;

	}

	public interface DeclaracionCtx {
		public TS tsh_exp();

		public Integer dirh_exp();

		public Integer nivelh_exp();

		public Integer etqh_exp();
	}

	// PARAMETROSFORMALES
	abstract public class ParametrosFormales {
		protected ParametrosFormales() {

			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});

			dir = new Atributo<Integer>();
			dir.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return dir_exp();
				}
			});

			params = new Atributo<List<Modo>>(); 
			  params.fijaExpresion(new ExpSem<List<Modo>>() 
			         {public List<Modo> val() { 
			               return params_exp(); }});

			ts = new Atributo<TS>();
			ts.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ts_exp();
				}
			});

			// Heredados

			nivelh = new Atributo<Integer>();
			nivelh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.nivelh_exp();
				}
			});

			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});

		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<Integer> dir() {
			return dir;
		}

		protected abstract Integer dir_exp();

		public Atributo<List<Modo>> params() {
			 return params;
		 } 
		 
		 protected abstract List<Modo> params_exp();

		public Atributo<TS> ts() {
			return ts;
		}

		protected abstract TS ts_exp();

		public Atributo<Integer> nivelh() {
			return nivelh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		public void registraCtx(ParametrosFormalesCtx ctx) {
			this.ctx = ctx;
		}

		private ParametrosFormalesCtx ctx;

		private Atributo<Error> error;
		private Atributo<Integer> dir;
		private Atributo<List<Modo>> params;
		private Atributo<TS> ts;
		private Atributo<TS> tsh;
		private Atributo<Integer> nivelh;

	}

	public interface ParametrosFormalesCtx {
		public TS tsh_exp();

		public Integer nivelh_exp();

	}

	abstract public class ListaParametrosFormales {
		protected ListaParametrosFormales() {

				
			params = new Atributo<List<Modo>>(); 
			params.fijaExpresion(new
					ExpSem<List<Modo>>() {
				public List<Modo> val() { 
					return params_exp(); }});
			
			ts = new Atributo<TS>();
			ts.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ts_exp();
				}
			});
			dir = new Atributo<Integer>();
			dir.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return dir_exp();
				}
			});
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			nivelh = new Atributo<Integer>();
			nivelh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.nivelh_exp();
				}
			});
		}

		// Atributos de la clase

		public Atributo<List<Modo>> params() {
			return params;
			} 
		protected abstract	List<Modo> params_exp();

		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<TS> ts() {
			return ts;
		}

		protected abstract TS ts_exp();

		public Atributo<Integer> dir() {
			return dir;
		}

		protected abstract Integer dir_exp();

		// Atributos Heredados
		public Atributo<Integer> nivelh() {
			return nivelh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		// Contexto
		public void registraCtx(ListaParametrosFormalesCtx ctx) {
			this.ctx = ctx;
		}

		private ListaParametrosFormalesCtx ctx;

		private Atributo<Error> error;
		private Atributo<Integer> dir;
		private Atributo<List<Modo>> params;
		private Atributo<TS> ts;
		private Atributo<TS> tsh;
		private Atributo<Integer> nivelh;
	}

	// Contexto de ListaParametrosFormales
	public interface ListaParametrosFormalesCtx {
		public TS tsh_exp();

		public Integer nivelh_exp();
	}

	abstract public class ParametroFormal {
		protected ParametroFormal() {
			clase = new Atributo<Clase>();
			clase.fijaExpresion(new ExpSem<Clase>() {
				public Clase val() {
					return clase_exp();
				}
			});
			iden = new Atributo<String>();
			iden.fijaExpresion(new ExpSem<String>() {
				public String val() {
					return iden_exp();
				}
			});
			
			modo = new Atributo<Modo>(); 
			modo.fijaExpresion(new ExpSem<Modo>(){
				public Modo val() { 
					return modo_exp(); 
				}
			});

		}

		// Atributos de la clase
		public Atributo<Clase> clase() {
			return clase;
		}

		protected abstract Clase clase_exp();

		public Atributo<String> iden() {
			return iden;
		}

		protected abstract String iden_exp();

		public Atributo<Modo> modo() {return modo;} 
		
		protected abstract Modo	modo_exp();

		// No tiene atributos heredados -> No contexto

		private Atributo<Clase> clase;
		private Atributo<String> iden;
		private Atributo<Modo> modo;

	}

	abstract public class Cuerpo {
		protected Cuerpo() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});

			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});

			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		// Atributos Heredados
		public Atributo<Integer> etqh() {
			return etqh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		// Contexto
		public void registraCtx(CuerpoCtx ctx) {
			this.ctx = ctx;
		}

		private CuerpoCtx ctx;

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de Cuerpo
	public interface CuerpoCtx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class Instrucciones {
		protected Instrucciones() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});

			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		// Atributos Heredados
		public Atributo<Integer> etqh() {
			return etqh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		// Contexto
		public void registraCtx(InstruccionesCtx ctx) {
			this.ctx = ctx;
		}

		private InstruccionesCtx ctx;

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de Instrucciones
	public interface InstruccionesCtx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class Instruccion {
		protected Instruccion() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		// Atributos Heredados
		public Atributo<Integer> etqh() {
			return etqh;
		}

		public Atributo<TS> tsh() {
			return tsh;
		}

		// Contexto
		public void registraCtx(InstruccionCtx ctx) {
			this.ctx = ctx;
		}

		private InstruccionCtx ctx;

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de Instruccion
	public interface InstruccionCtx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class ParametrosReales {
		protected ParametrosReales() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			
			nparams = new Atributo<Integer>(); 
			nparams.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() { 
					return nparams_exp(); }});
			

			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});

			subprogramah = new Atributo<String>(); 
			subprogramah.fijaExpresion(new ExpSem<String>() {
				public String val() { 
					return ctx.subprogramah_exp(); 
					}
				});
			 

			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Integer> nparams() {return nparams;} 
		protected abstract Integer nparams_exp();
		

		// Atributos Heredados
		public Atributo<Integer> etqh() {
			return etqh;
		}
		
		public Atributo<TS> tsh() {
			return tsh;
		}
		public Atributo<String> subprogramah() {return subprogramah;}

		// Contexto
		public void registraCtx(ParametrosRealesCtx ctx) {
			this.ctx = ctx;
		}

		private ParametrosRealesCtx ctx;

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Integer> nparams;
		private Atributo<String> subprogramah;
		private Atributo<Integer> etqh;
		private Atributo<TS> tsh;
	}

	// Contexto de ParametrosReales
	public interface ParametrosRealesCtx {
		
		public String subprogramah_exp();
		public Integer etqh_exp();
		public TS tsh_exp();
	}

	abstract public class ListaParametrosReales {
		protected ListaParametrosReales() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			
			
			 nparams = new Atributo<Integer>(); 
			 nparams.fijaExpresion(new
			  ExpSem<Integer>() {
				 public Integer val() { 
					 return nparams_exp(); }});
			 
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			
			 subprogramah = new Atributo<String>();
			 subprogramah.fijaExpresion(new ExpSem<String>() {
				 public String val() { 
					 return ctx.subprogramah_exp();
				}
			});
			 
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Integer> nparams() {return nparams;} 
		protected abstract Integer nparams_exp();
		

		// Atributos Heredados
		public Atributo<Integer> etqh() {
			return etqh;
		}

		public Atributo<String> subprogramah() {return subprogramah;}
		public Atributo<TS> tsh() {
			return tsh;
		}

		// Contexto
		public void registraCtx(ListaParametrosRealesCtx ctx) {
			this.ctx = ctx;
		}

		private ListaParametrosRealesCtx ctx;

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Integer> nparams;
		private Atributo<TS> tsh;
		private Atributo<String> subprogramah;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface ListaParametrosRealesCtx {
		 public String subprogramah_exp();
		public Integer etqh_exp();

		public TS tsh_exp();
	}

	abstract public class ParteElse {
		protected ParteElse() {
			error = new Atributo<Error>();
			error.fijaExpresion(new ExpSem<Error>() {
				public Error val() {
					return error_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			
			ir_f = new Atributo<Integer>(); 
			ir_f.fijaExpresion(new ExpSem<Integer>()
			 {public Integer val() { return ir_f_exp(); }});
			 
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});

			// TODO
			// Revisar en las hojas de la gramatica si es etq()+1 o etqh()

		}

		// Atributos de la clase
		public Atributo<Error> error() {
			return error;
		}

		protected abstract Error error_exp();

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Integer> ir_f() {return ir_f;} 
		protected abstract Integer ir_f_exp();
		

		// Atributos Heredados
		public Atributo<TS> tsh() {
			return tsh;
		}
		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(ParteElseCtx ctx) {
			this.ctx = ctx;
		}

		private ParteElseCtx ctx;

		private Atributo<Error> error;
		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Integer> ir_f;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface ParteElseCtx {
		public TS tsh_exp();
		public Integer etqh_exp();
	}

	abstract public class Exp0 {
		protected Exp0() {
			esDesignador = new Atributo<Boolean>();
			esDesignador.fijaExpresion(new ExpSem<Boolean>() {
				public Boolean val() {
					return esDesignador_exp();
				}
			});
			tipo = new Atributo<Tipo>();
			tipo.fijaExpresion(new ExpSem<Tipo>() {
				public Tipo val() {
					return tipo_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Tipo> tipo() {
			return tipo;
		}

		protected abstract Tipo tipo_exp();

		public Atributo<Boolean> esDesignador() {
			return esDesignador;
		}

		protected abstract Boolean esDesignador_exp();

		// Atributos Heredados
		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(Exp0Ctx ctx) {
			this.ctx = ctx;
		}

		private Exp0Ctx ctx;

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Tipo> tipo;
		private Atributo<Boolean> esDesignador;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface Exp0Ctx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class Exp1 {
		protected Exp1() {
			esDesignador = new Atributo<Boolean>();
			esDesignador.fijaExpresion(new ExpSem<Boolean>() {
				public Boolean val() {
					return esDesignador_exp();
				}
			});
			tipo = new Atributo<Tipo>();
			tipo.fijaExpresion(new ExpSem<Tipo>() {
				public Tipo val() {
					return tipo_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Tipo> tipo() {
			return tipo;
		}

		protected abstract Tipo tipo_exp();

		public Atributo<Boolean> esDesignador() {
			return esDesignador;
		}

		protected abstract Boolean esDesignador_exp();

		// Atributos Heredados
		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(Exp1Ctx ctx) {
			this.ctx = ctx;
		}

		private Exp1Ctx ctx;

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Tipo> tipo;
		private Atributo<Boolean> esDesignador;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface Exp1Ctx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class Exp2 {
		protected Exp2() {
			esDesignador = new Atributo<Boolean>();
			esDesignador.fijaExpresion(new ExpSem<Boolean>() {
				public Boolean val() {
					return esDesignador_exp();
				}
			});
			tipo = new Atributo<Tipo>();
			tipo.fijaExpresion(new ExpSem<Tipo>() {
				public Tipo val() {
					return tipo_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Tipo> tipo() {
			return tipo;
		}

		protected abstract Tipo tipo_exp();

		public Atributo<Boolean> esDesignador() {
			return esDesignador;
		}

		protected abstract Boolean esDesignador_exp();

		// Atributos Heredados
		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(Exp2Ctx ctx) {
			this.ctx = ctx;
		}

		private Exp2Ctx ctx;

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Tipo> tipo;
		private Atributo<Boolean> esDesignador;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface Exp2Ctx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class Exp3 {
		protected Exp3() {
			esDesignador = new Atributo<Boolean>();
			esDesignador.fijaExpresion(new ExpSem<Boolean>() {
				public Boolean val() {
					return esDesignador_exp();
				}
			});
			tipo = new Atributo<Tipo>();
			tipo.fijaExpresion(new ExpSem<Tipo>() {
				public Tipo val() {
					return tipo_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Tipo> tipo() {
			return tipo;
		}

		protected abstract Tipo tipo_exp();

		public Atributo<Boolean> esDesignador() {
			return esDesignador;
		}

		protected abstract Boolean esDesignador_exp();

		// Atributos Heredados
		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(Exp3Ctx ctx) {
			this.ctx = ctx;
		}

		private Exp3Ctx ctx;

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Tipo> tipo;
		private Atributo<Boolean> esDesignador;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface Exp3Ctx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class Exp4 {
		protected Exp4() {
			esDesignador = new Atributo<Boolean>();
			esDesignador.fijaExpresion(new ExpSem<Boolean>() {
				public Boolean val() {
					return esDesignador_exp();
				}
			});
			tipo = new Atributo<Tipo>();
			tipo.fijaExpresion(new ExpSem<Tipo>() {
				public Tipo val() {
					return tipo_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
			etq = new Atributo<Integer>();
			etq.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return etq_exp();
				}
			});
			tsh = new Atributo<TS>();
			tsh.fijaExpresion(new ExpSem<TS>() {
				public TS val() {
					return ctx.tsh_exp();
				}
			});
			etqh = new Atributo<Integer>();
			etqh.fijaExpresion(new ExpSem<Integer>() {
				public Integer val() {
					return ctx.etqh_exp();
				}
			});
		}

		// Atributos de la clase
		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<Integer> etq() {
			return etq;
		}

		protected abstract Integer etq_exp();

		public Atributo<Tipo> tipo() {
			return tipo;
		}

		protected abstract Tipo tipo_exp();

		public Atributo<Boolean> esDesignador() {
			return esDesignador;
		}

		protected abstract Boolean esDesignador_exp();

		// Atributos Heredados
		public Atributo<TS> tsh() {
			return tsh;
		}

		public Atributo<Integer> etqh() {
			return etqh;
		}

		// Contexto
		public void registraCtx(Exp4Ctx ctx) {
			this.ctx = ctx;
		}

		private Exp4Ctx ctx;

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<Integer> etq;
		private Atributo<Tipo> tipo;
		private Atributo<Boolean> esDesignador;
		private Atributo<TS> tsh;
		private Atributo<Integer> etqh;
	}

	// Contexto de ParametrosReales
	public interface Exp4Ctx {
		public TS tsh_exp();

		public Integer etqh_exp();
	}

	abstract public class OpComparacion {
		protected OpComparacion() {
			op = new Atributo<CatLexica>();
			op.fijaExpresion(new ExpSem<CatLexica>() {
				public CatLexica val() {
					return op_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
		}

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<CatLexica> op() {
			return op;
		}

		protected abstract CatLexica op_exp();

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<CatLexica> op;
	}

	abstract public class OpAditivo {
		protected OpAditivo() {
			op = new Atributo<CatLexica>();
			op.fijaExpresion(new ExpSem<CatLexica>() {
				public CatLexica val() {
					return op_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
		}

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<CatLexica> op() {
			return op;
		}

		protected abstract CatLexica op_exp();

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<CatLexica> op;
	}

	abstract public class OpMultiplicativo {
		protected OpMultiplicativo() {
			op = new Atributo<CatLexica>();
			op.fijaExpresion(new ExpSem<CatLexica>() {
				public CatLexica val() {
					return op_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
		}

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<CatLexica> op() {
			return op;
		}

		protected abstract CatLexica op_exp();

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<CatLexica> op;
	}

	abstract public class OpUnario {
		protected OpUnario() {
			op = new Atributo<CatLexica>();
			op.fijaExpresion(new ExpSem<CatLexica>() {
				public CatLexica val() {
					return op_exp();
				}
			});
			cod = new Atributo<ArrayList<Insts>>();
			cod.fijaExpresion(new ExpSem<ArrayList<Insts>>() {
				public ArrayList<Insts> val() {
					return cod_exp();
				}
			});
		}

		public Atributo<ArrayList<Insts>> cod() {
			return cod;
		}

		protected abstract ArrayList<Insts> cod_exp();

		public Atributo<CatLexica> op() {
			return op;
		}

		protected abstract CatLexica op_exp();

		private Atributo<ArrayList<Insts>> cod;
		private Atributo<CatLexica> op;
	}

	// //////////Definicion de las clases////////////
	

	public class ProgramaR1 extends Programa {
		public ProgramaR1(Declaraciones decs, Cuerpo cuerpo) {
			super();
			this.decs = decs;
			this.cuerpo = cuerpo;
			decs.registraCtx(new DeclaracionesCtx() {
				public TS tsh_exp() {
					return creaTS();
				}

				public Integer dirh_exp() {
					return new Integer(0);
				}

				public Integer nivelh_exp() {
					return new Integer(0);
				}

				public Integer etqh_exp() {
					return numeroInstruccionesActivacionProgramaPrincipal();
				}
			});
			cuerpo.registraCtx(new CuerpoCtx() {
				public TS tsh_exp() {
					return ProgramaR1.this.decs.ts().val();
				}
				public Integer etqh_exp() {
					return ProgramaR1.this.decs.etq().val();
				}
			});
			
			//Dependencias
			cuerpo.tsh().ponDependencias(decs.ts());
			cuerpo.etqh().ponDependencias(decs.etq());
			
			error().ponDependencias(decs.error(),cuerpo.error());
			cod().ponDependencias(decs.dir(),decs.etq(),decs.anidamiento(),decs.cod(),cuerpo.cod());
		
		}

		protected Error error_exp() {
			return joinErrors(decs.error().val(), cuerpo.error().val());
		}

		protected ArrayList<Insts> cod_exp() {
			return concat(codigoActivacionProgramaPrincipal(decs.dir().val(), 
					decs.etq().val(),decs.anidamiento().val()),concat(decs.cod().val(),cuerpo.cod().val()));
		}

		private Declaraciones decs;
		private Cuerpo cuerpo;
	}

	public class DeclaracionesR1 extends Declaraciones {
		public DeclaracionesR1(ListaDeclaraciones listaDecs) {
			super();
			this.listaDecs = listaDecs;
			listaDecs.registraCtx(new ListaDeclaracionesCtx() {
				public TS tsh_exp() {
					return DeclaracionesR1.this.tsh().val();
				}
				public Integer dirh_exp() {
					return DeclaracionesR1.this.dirh().val();
				}
				public Integer nivelh_exp() {
					return DeclaracionesR1.this.nivelh().val();
				}
				public Integer etqh_exp() {
					return DeclaracionesR1.this.etqh().val();
				}
			});
			
			listaDecs.tsh().ponDependencias(tsh());
			listaDecs.dirh().ponDependencias(dirh());
			listaDecs.nivelh().ponDependencias(nivelh());
			listaDecs.etqh().ponDependencias(etqh());
			
			ts().ponDependencias(listaDecs.ts());
			dir().ponDependencias(listaDecs.dir());
			error().ponDependencias(listaDecs.error());
			etq().ponDependencias(listaDecs.etq());
			anidamiento().ponDependencias(listaDecs.anidamiento());
			cod().ponDependencias(listaDecs.cod());
		}

		protected Error error_exp() {
			return listaDecs.error().val();
		}

		protected ArrayList<Insts> cod_exp() {
			return listaDecs.cod().val();
		}

		protected Integer dir_exp() {
			return listaDecs.dir().val();
		}

		protected TS ts_exp() {
			return listaDecs.ts().val();
		}

		protected Integer etq_exp() {
			return listaDecs.etq().val();
		}

		protected Integer anidamiento_exp() {
			return listaDecs.anidamiento().val();
		}
		
		private ListaDeclaraciones listaDecs;
	}

	public class DeclaracionesR2 extends Declaraciones {
		public DeclaracionesR2() {
			super();
			
			ts().ponDependencias(tsh());
			dir().ponDependencias(dirh());
			etq().ponDependencias(etqh());
					}
		
		protected Error error_exp() {
			return noError();
		}

		protected ArrayList<Insts> cod_exp() {
			return programaVacio();
		}

		protected Integer dir_exp() {
			return this.dirh().val();
		}

		protected TS ts_exp() {
			return this.tsh().val();
		}

		protected Integer etq_exp() {
			return this.etqh().val();
		}

		protected Integer anidamiento_exp() {
			return new Integer(0);
		}
		

	}

	public class ListaDeclaracionesR1 extends ListaDeclaraciones {
		public ListaDeclaracionesR1(ListaDeclaraciones listaDecs, Declaracion dec) {
			super();
			this.listaDecs = listaDecs;
			this.dec=dec;
			listaDecs.registraCtx(new ListaDeclaracionesCtx() {
				public TS tsh_exp() {
					return ListaDeclaracionesR1.this.tsh().val();
				}
				public Integer dirh_exp() {
					return ListaDeclaracionesR1.this.dirh().val();
				}
				public Integer nivelh_exp() {
					return ListaDeclaracionesR1.this.nivelh().val();
				}
				public Integer etqh_exp() {
					return ListaDeclaracionesR1.this.etqh().val();
				}
			});
			dec.registraCtx(new DeclaracionCtx() {
				public TS tsh_exp() {
					return ListaDeclaracionesR1.this.listaDecs.ts().val();
				}
				public Integer dirh_exp() {
					return ListaDeclaracionesR1.this.listaDecs.dir().val();
					//return ListaDeclaracionesR1.this.dirh().val();
				}
				public Integer nivelh_exp() {
					return ListaDeclaracionesR1.this.nivelh().val();
				}
				public Integer etqh_exp() {
					return ListaDeclaracionesR1.this.listaDecs.etq().val();
				}
			});
			
			//Dependencias
			listaDecs.tsh().ponDependencias(tsh());
			listaDecs.nivelh().ponDependencias(nivelh());
			listaDecs.dirh().ponDependencias(dirh());
			listaDecs.etqh().ponDependencias(etqh());
			
			
			dec.nivelh().ponDependencias(nivelh());
			dec.dirh().ponDependencias(listaDecs.dir());
			//dec.dirh().ponDependencias(dirh());
			dec.tsh().ponDependencias(listaDecs.ts()); 
			dec.etqh().ponDependencias(listaDecs.etq());
			
			ts().ponDependencias(listaDecs.ts(),dec.iden(),dec.clase(),dec.tipo(),dec.dir(),nivelh());
			dir().ponDependencias(listaDecs.dir(),dec.tam());
			error().ponDependencias(listaDecs.error(),dec.error(),listaDecs.ts(),dec.iden());
			etq().ponDependencias(dec.etq());
			cod().ponDependencias(listaDecs.cod(),dec.cod());
			anidamiento().ponDependencias(listaDecs.anidamiento(),dec.anidamiento());
			
			
		}

		protected Error error_exp() {
			return joinErrors(this.listaDecs.error().val(), 
					joinErrors(this.dec.error().val(), 
							existeSimbEnUltimoNivel(this.listaDecs.ts().val(),this.dec.iden().val())));
		}

		protected Integer dir_exp() {
			return new Integer(this.listaDecs.dir().val()+this.dec.tam().val());
		}

		protected TS ts_exp() {
			return aniadeSimb(this.listaDecs.ts().val(),this.dec.iden().val(),
					this.dec.clase().val(),this.dec.tipo().val(),
					this.dec.dir().val(),this.nivelh().val());
		}

		protected Integer etq_exp() {
			return this.dec.etq().val();
		}

		protected Integer anidamiento_exp() {
			return Math.max(this.listaDecs.anidamiento().val(),this.dec.anidamiento().val());
		}

		protected ArrayList<Insts> cod_exp() {
			return concat(this.listaDecs.cod().val(), this.dec.cod().val());
		}
		
		private ListaDeclaraciones listaDecs;
		private Declaracion dec;
	}

	public class ListaDeclaracionesR2 extends ListaDeclaraciones {
		public ListaDeclaracionesR2(Declaracion dec) {
			super();
			this.dec=dec;
			dec.registraCtx(new DeclaracionCtx() {
				public TS tsh_exp() {
					return ListaDeclaracionesR2.this.tsh().val();
				}
				public Integer dirh_exp() {
					return ListaDeclaracionesR2.this.dirh().val();
				}
				public Integer nivelh_exp() {
					return ListaDeclaracionesR2.this.nivelh().val();
				}
				public Integer etqh_exp() {
					return ListaDeclaracionesR2.this.etqh().val();
				}
			});
			
			//Dependencias
			dec.nivelh().ponDependencias(nivelh());
			dec.dirh().ponDependencias(dirh());
			dec.tsh().ponDependencias(tsh());
			dec.etqh().ponDependencias(etqh());
			
			ts().ponDependencias(tsh(),dec.iden(),dec.clase(),dec.tipo(),dec.dir(),nivelh());
			dir().ponDependencias(dirh(),dec.tam());
			error().ponDependencias(dec.error(),tsh(),dec.iden());
			etq().ponDependencias(dec.etq());
			cod().ponDependencias(dec.cod());
			anidamiento().ponDependencias(dec.anidamiento());
			
		}

		protected Error error_exp() {
			return joinErrors(this.dec.error().val(), existeSimbEnUltimoNivel(
					this.tsh().val(),this.dec.iden().val()));
		}

		protected Integer dir_exp() {
			return this.dirh().val()+ this.dec.tam().val();
		}

		protected TS ts_exp() {
			return aniadeSimb(this.tsh().val(),this.dec.iden().val(),this.dec.clase().val(),
					this.dec.tipo().val(), this.dec.dir().val(),this.nivelh().val());
		}

		protected Integer etq_exp() {
			return this.dec.etq().val();
		}

		protected Integer anidamiento_exp() {
			return this.dec.anidamiento().val();
		}

		protected ArrayList<Insts> cod_exp() {
			return this.dec.cod().val();
		}
		
		private Declaracion dec;
	}

	public class DeclaracionR1 extends Declaracion {
		public DeclaracionR1(Token iden) {
			super();
			this.iden=iden;
			
			//Dependencias
			dir().ponDependencias(dirh());
			etq().ponDependencias(etqh());
			 
		}

		protected Error error_exp() {
			return noError();
		}

		protected Integer dir_exp() {
			return this.dirh().val();
		}

		protected Integer etq_exp() {
			return this.etqh().val();
		}

		protected Integer anidamiento_exp() {
			return new Integer(0);
		}

		protected ArrayList<Insts> cod_exp() {
			return programaVacio();
		}

		protected Clase clase_exp() {
			return Clase.var;
		}

		protected Tipo tipo_exp() {
			return new TipoNumerico();
		}

		protected Integer tam_exp() {
			return new Integer(1);
		}

		protected String iden_exp() {
			return iden.leeLexema();
		}
		
		private Token iden;
	}

	public class DeclaracionR2 extends Declaracion {
		public DeclaracionR2(Token IDEN, ParametrosFormales paramsFormales, Declaraciones decs, Cuerpo cuerpo) {
			super();
			this.IDEN=IDEN;
			this.paramsFormales=paramsFormales;
			this.decs=decs;
			this.cuerpo=cuerpo;
			paramsFormales.registraCtx(new ParametrosFormalesCtx() {
				public TS tsh_exp() {
			           return creaNivel(DeclaracionR2.this.tsh().val());
				}
				public Integer nivelh_exp() {
					return DeclaracionR2.this.nivelh().val()+new Integer(1);
				}
			});
			decs.registraCtx(new DeclaracionesCtx() {
				public TS tsh_exp() {
				    return DeclaracionR2.this.paramsFormales.ts().val();
				}
				public Integer dirh_exp() {
					return DeclaracionR2.this.paramsFormales.dir().val();				
					}
				public Integer nivelh_exp() {
					return DeclaracionR2.this.nivelh().val()+new Integer(1);	
				}
				public Integer etqh_exp() {
					return DeclaracionR2.this.etqh().val();	
				}
			});
			cuerpo.registraCtx(new CuerpoCtx() {
				public TS tsh_exp() {
					return aniadeSimb(DeclaracionR2.this.decs.ts().val(), DeclaracionR2.this.IDEN.leeLexema(),Clase.proc,
							new TipoProcedimiento(DeclaracionR2.this.paramsFormales.params().val()),DeclaracionR2.this.decs.etq().val(),
							DeclaracionR2.this.nivelh().val()+1);	
					}
				public Integer etqh_exp() {
					return  DeclaracionR2.this.decs.etq().val()+numeroInstruccionesPrologo();	
				}
			});
			
			//Dependencias
			decs.nivelh().ponDependencias(nivelh());
			decs.tsh().ponDependencias(paramsFormales.ts());
			decs.dirh().ponDependencias(paramsFormales.dir());
			decs.etqh().ponDependencias(etqh());
			
			paramsFormales.nivelh().ponDependencias(nivelh());
			paramsFormales.tsh().ponDependencias(tsh());
			paramsFormales.nivelh().ponDependencias( );
			
			cuerpo.tsh().ponDependencias(decs.ts(),paramsFormales.params(),decs.etq(),nivelh());
			cuerpo.etqh().ponDependencias(decs.etq());
			
			dir().ponDependencias(decs.etq());
			error().ponDependencias(paramsFormales.error(),decs.error(),cuerpo.error());
			cod().ponDependencias(decs.cod(),decs.dir(),nivelh(),cuerpo.cod());
			etq().ponDependencias(cuerpo.etq());
			anidamiento().ponDependencias(decs.anidamiento());
			tipo().ponDependencias(paramsFormales.params());
			
			
		}

		protected Error error_exp() {
			return joinErrors(this.paramsFormales.error().val(),joinErrors(this.decs.error().val(), this.cuerpo.error().val()));
		}

		protected Integer dir_exp() {
			return this.decs.etq().val();	
		}

		protected Integer etq_exp() {
			return this.cuerpo.etq().val()+numeroInstruccionesEpilogo();	
		}

		protected Integer anidamiento_exp() {
			return this.decs.anidamiento().val()+new Integer(1);	
		}

		protected ArrayList<Insts> cod_exp() {
			return concat( this.decs.cod().val(),
							concat(codigoPrologo(this.decs.dir().val(), this.nivelh().val()+1),
							concat(this.cuerpo.cod().val(),codigoEpilogo(this.decs.dir().val(), this.nivelh().val()+1))));
		}

		protected Clase clase_exp() {
			return Clase.proc;
		}

		protected Tipo tipo_exp() {
			return new TipoProcedimiento(this.paramsFormales.params().val());
		}

		protected Integer tam_exp() {
			return new Integer(0);
		}

		protected String iden_exp() {
			return this.IDEN.leeLexema();
		}
		private Token IDEN;
		private ParametrosFormales paramsFormales;
		private Declaraciones decs;
		private Cuerpo cuerpo;
	}

	public class ParametrosFormalesR1 extends ParametrosFormales {
		public ParametrosFormalesR1(ListaParametrosFormales listaParamFormales) {
		   super();
		   this.listaParamFormales=listaParamFormales;
		   listaParamFormales.registraCtx(new ListaParametrosFormalesCtx() {

			 
			public TS tsh_exp() {
				 return ParametrosFormalesR1.this.tsh().val();
			}

			 
			public Integer nivelh_exp() {
				 return ParametrosFormalesR1.this.nivelh().val();
			}
		   });
		   
		 //Dependencias
		   listaParamFormales.tsh().ponDependencias(tsh());
		   listaParamFormales.nivelh().ponDependencias(nivelh());
		    
		   params().ponDependencias(listaParamFormales.params());
		   ts().ponDependencias(listaParamFormales.ts());
		   dir().ponDependencias(listaParamFormales.dir());
		   error().ponDependencias(listaParamFormales.error());
		}
		
		protected Error error_exp() {
			return this.listaParamFormales.error().val();
		}

		protected Integer dir_exp() {
			return this.listaParamFormales.dir().val();
		}

		protected TS ts_exp() {
			return this.listaParamFormales.ts().val();
		}
		
		private ListaParametrosFormales listaParamFormales;

		protected List<Modo> params_exp() {
			return this.listaParamFormales.params().val();
		}
	}

	public class ParametrosFormalesR2 extends ParametrosFormales {
		public ParametrosFormalesR2( ) {
		   super();
		   
		   //Dependencias
		   ts().ponDependencias(tsh());
		}

		protected Error error_exp() {
			return noError();
		}

		protected Integer dir_exp() {
			return new Integer(0);
		}

		protected TS ts_exp() {
			return this.tsh().val();
		}

		@Override
		protected List<Modo> params_exp() {
			return new ArrayList<Modo>();
		}
		
	}

	public class ListaParametrosFormalesR1 extends ListaParametrosFormales {
		public ListaParametrosFormalesR1(ListaParametrosFormales listaParamFormales,ParametroFormal paramFormal) 
		{   super();
			this.listaParamFormales=listaParamFormales;
			this.paramFormal=paramFormal;
			listaParamFormales.registraCtx(new ListaParametrosFormalesCtx() {
				
				@Override
				public TS tsh_exp() {
					 return ListaParametrosFormalesR1.this.tsh().val();
				}
				
				@Override
				public Integer nivelh_exp() {
					 return ListaParametrosFormalesR1.this.nivelh().val();
				}
			});
			
			//Dependencias
			listaParamFormales.tsh().ponDependencias(tsh());
			listaParamFormales.nivelh().ponDependencias(nivelh());
	
			params().ponDependencias(listaParamFormales.params(),paramFormal.modo());
			ts().ponDependencias(listaParamFormales.ts(),paramFormal.iden(),paramFormal.clase(),listaParamFormales.dir(),nivelh());
		    dir().ponDependencias(listaParamFormales.dir());
		    error().ponDependencias(listaParamFormales.error(),listaParamFormales.ts(),paramFormal.iden());
		}
		
		protected Error error_exp() {
			 return joinErrors(this.listaParamFormales.error().val(),
					 			existeSimbEnUltimoNivel(this.listaParamFormales.ts().val(),this.paramFormal.iden().val()));
		}
		protected TS ts_exp() {
			return aniadeSimb(this.listaParamFormales.ts().val(),this.paramFormal.iden().val()
								,this.paramFormal.clase().val(),new TipoNumerico(),this.listaParamFormales.dir().val(),this.nivelh().val());
		}
		protected Integer dir_exp() {
			return new Integer (this.listaParamFormales.dir().val() +1) ;
		}
		
		
		
		private ListaParametrosFormales listaParamFormales;
		private ParametroFormal paramFormal;
		@Override
		protected List<Modo> params_exp() {
			return aniadeA(this.listaParamFormales.params().val(), this.paramFormal.modo().val());

		}
	}

	public class ListaParametrosFormalesR2 extends ListaParametrosFormales {
		public ListaParametrosFormalesR2(ParametroFormal paramFormal) 
		{
			super();
			this.paramFormal = paramFormal;
			
			//Dependencias
			params().ponDependencias(paramFormal.modo());
			ts().ponDependencias(tsh(),paramFormal.iden(),paramFormal.clase(),nivelh());
			error().ponDependencias(tsh(),paramFormal.iden());
			
		}
		
		protected Error error_exp() {
			  return existeSimbEnUltimoNivel(this.tsh().val(),this.paramFormal.iden().val());
		}


		protected TS ts_exp() {
			return aniadeSimb(this.tsh().val(),this.paramFormal.iden().val()
					,this.paramFormal.clase().val(),new TipoNumerico(),0,this.nivelh().val());
		}


		protected Integer dir_exp() {
			return new Integer (1);
		}
		
		private ParametroFormal paramFormal;

		protected List<Modo> params_exp() {
			return nuevaLista(this.paramFormal.modo().val());
		}
	}

	public class ParametroFormalR1 extends ParametroFormal {
		public ParametroFormalR1(Token IDEN) {
		super();
		this.IDEN=IDEN;
	    }

		protected Clase clase_exp() {
			return Clase.var;
		}

		protected String iden_exp() {
			return this.IDEN.leeLexema();
		}
		
		private Token IDEN;

		protected Modo modo_exp() {
			return Modo.valor;
		}
	}

	public class ParametroFormalR2 extends ParametroFormal {
		public ParametroFormalR2(Token IDEN) {
			super();
			this.IDEN=IDEN;
		}
		
		
		protected Clase clase_exp() {
			return Clase.pvar;
		}

		protected String iden_exp() {
			return this.IDEN.leeLexema();
		}
		private Token IDEN;

		protected Modo modo_exp() {
			return Modo.var;
		}
	}

	public class CuerpoR1 extends Cuerpo {
		public CuerpoR1(Instrucciones insts){
			super();
			this.insts = insts;
			insts.registraCtx(new InstruccionesCtx() {
				
				public TS tsh_exp() {
				     return CuerpoR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return CuerpoR1.this.etqh().val();
				}
			});
			
			//Dependencias
			insts.tsh().ponDependencias(tsh());
			insts.etqh().ponDependencias(etqh());
			
			error().ponDependencias(insts.error());
			etq().ponDependencias(insts.etq());
			cod().ponDependencias(insts.cod());
			
		}

		protected Error error_exp() {
			return this.insts.error().val();
		}

		protected ArrayList<Insts> cod_exp() {
			 return this.insts.cod().val();
		}

		protected Integer etq_exp() {
			  return this.insts.etq().val();
		}
		
		private Instrucciones insts;
	}

	public class InstruccionesR1 extends Instrucciones {
		public InstruccionesR1(Instrucciones insts, Instruccion inst){
			super();
			this.insts = insts;
			this.inst = inst;
			insts.registraCtx(new InstruccionesCtx() {
				
				public TS tsh_exp() {
				     return InstruccionesR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return InstruccionesR1.this.etqh().val();
				}
			});
			inst.registraCtx(new InstruccionCtx() {
				
				public TS tsh_exp() {
					 return InstruccionesR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return InstruccionesR1.this.insts.etq().val();
				}
			});
			
			//Dependencias
			insts.tsh().ponDependencias(tsh());
			insts.etqh().ponDependencias(etqh());
			
			inst.tsh().ponDependencias(tsh());
			inst.etqh().ponDependencias(insts.etq());
			
			error().ponDependencias(insts.error(),inst.error());
			etq().ponDependencias(inst.etq());
			cod().ponDependencias(insts.cod(),inst.cod());
			
		}

		protected Error error_exp() {
			return joinErrors(this.insts.error().val(),this.inst.error().val());
		}

		protected ArrayList<Insts> cod_exp() {
			 return concat(this.insts.cod().val(),this.inst.cod().val());
		}

		protected Integer etq_exp() {
			 return new Integer (this.inst.etq().val());
		}
		
		private Instrucciones insts;
		private Instruccion inst;
	}

	public class InstruccionesR2 extends Instrucciones {
		public InstruccionesR2(Instruccion inst){
			super();
			this.inst = inst;
			inst.registraCtx(new InstruccionCtx() {
				
				public TS tsh_exp() {
					 return InstruccionesR2.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return InstruccionesR2.this.etqh().val();
				}
			});
			
			//Dependencias
			inst.tsh().ponDependencias(tsh());
			inst.etqh().ponDependencias(etqh());
			
			error().ponDependencias(inst.error());
			etq().ponDependencias(inst.etq());
			cod().ponDependencias(inst.cod());
		}

		protected Error error_exp() {
			return this.inst.error().val();
		}

		protected ArrayList<Insts> cod_exp() {
			 return this.inst.cod().val();
		}

		protected Integer etq_exp() {
			 return new Integer(this.inst.etq().val());
		}
		
		private Instruccion inst;
		
	}

	public class InstruccionR1 extends Instruccion {
		public InstruccionR1(Token IDEN,Exp0 exp0){
			super();
			this.IDEN = IDEN;
			this.exp0=exp0;
			exp0.registraCtx(new Exp0Ctx() {
				public TS tsh_exp() {
					 return InstruccionR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return InstruccionR1.this.etqh().val();
				}
			});
			
			//Dependencias
			exp0.tsh().ponDependencias(tsh());
			exp0.etqh().ponDependencias(etqh());
			
			error().ponDependencias(tsh(),exp0.tipo());
			etq().ponDependencias(exp0.etq(),tsh(),exp0.esDesignador());
			//etq().ponDependencias(exp0.etq(),tsh());
			cod().ponDependencias(tsh(),exp0.cod(),exp0.esDesignador());
			
			
		}

		protected Error error_exp() {
			 return asignacionCorrecta(this.tsh().val(),this.IDEN.leeLexema(),
					 this.exp0.tipo().val());
		}

		protected ArrayList<Insts> cod_exp() {
			 return codigoAsignacion(this.tsh().val(),this.IDEN.leeLexema(),
					 this.exp0.cod().val(),this.exp0.esDesignador().val());
		}

		protected Integer etq_exp() {
			 return new Integer(this.exp0.etq().val() + 
					 numeroInstruccionesAsignacion(this.IDEN.leeLexema(),this.tsh().val(),this.exp0.esDesignador().val()));
		}
		private Token IDEN;
		private Exp0 exp0;
	}

	public class InstruccionR2 extends Instruccion {
		public InstruccionR2(Token IDEN,ParametrosReales paramReales){
			super();
			this.IDEN=IDEN;
			this.paramReales=paramReales;
			paramReales.registraCtx(new ParametrosRealesCtx() {
				
				public Integer etqh_exp() {
					 return InstruccionR2.this.etqh().val();
				}

				 
				public TS tsh_exp() {
					 return InstruccionR2.this.tsh().val();
				}

				public String subprogramah_exp() {
					 return InstruccionR2.this.IDEN.leeLexema();
				}
			});
			
			//Dependencias
			paramReales.tsh().ponDependencias(tsh());
			paramReales.etqh().ponDependencias(etqh());
			
			error().ponDependencias(paramReales.error(),tsh(),paramReales.nparams());
			etq().ponDependencias(paramReales.etq());
			cod().ponDependencias(paramReales.cod(),tsh(),paramReales.etq());
			
		}

		protected Error error_exp() {
			 return joinErrors(this.paramReales.error().val(),
					 llamadaCorrecta(this.tsh().val(),this.IDEN.leeLexema(),
							 this.paramReales.nparams().val()));
		}

		protected ArrayList<Insts> cod_exp() {
			return concat(this.paramReales.cod().val(),
					      codigoFinLlamada(this.IDEN.leeLexema(),
					    		  this.tsh().val(),this.paramReales.etq().val()+
					    		  numeroInstruccionesFinLlamada()));
		}

		protected Integer etq_exp() {
			return new Integer(this.paramReales.etq().val()+numeroInstruccionesFinLlamada());
		}
		private Token IDEN;
		private ParametrosReales paramReales;
		
	}

	public class InstruccionR3 extends Instruccion {
		public InstruccionR3(Exp0 exp0,Instrucciones insts,ParteElse parteElse)
		{		super();
				this.exp0=exp0;
				this.insts=insts;
				this.parteElse=parteElse;
				exp0.registraCtx(new Exp0Ctx() {
					
					public TS tsh_exp() {
						 return InstruccionR3.this.tsh().val();
					}
					
					public Integer etqh_exp() {
						return InstruccionR3.this.etqh().val();
					}
				});
				 insts.registraCtx(new InstruccionesCtx() {
					
					public TS tsh_exp() {
						return InstruccionR3.this.tsh().val();
					}
					
					public Integer etqh_exp() {
						return new Integer(InstruccionR3.this.exp0.etq().val()+1);
					}
				});
				 parteElse.registraCtx(new ParteElseCtx() {
					
					 public TS tsh_exp() {
						 return InstruccionR3.this.tsh().val();
					}
					
					public Integer etqh_exp() {
						return InstruccionR3.this.insts.etq().val();
						//return InstruccionR3.this.insts.etqh().val();
					}
				});
				 
				 //Dependencias
				 exp0.tsh().ponDependencias(tsh());
				 exp0.etqh().ponDependencias(etqh());
				 
				 insts.tsh().ponDependencias(tsh());
				 insts.etqh().ponDependencias(exp0.etq());
				 
				 parteElse.tsh().ponDependencias(tsh());
				 parteElse.etqh().ponDependencias(insts.etq());
				 //parteElse.etqh().ponDependencias(insts.etqh());
				 
				 error().ponDependencias(exp0.tipo(),insts.error(),parteElse.error());
				 etq().ponDependencias(parteElse.etq());
				 cod().ponDependencias(exp0.cod(),parteElse.ir_f(),insts.cod(),parteElse.cod());
		}

		protected Error error_exp() {
			return joinErrors(condicionCorrecta(this.exp0.tipo().val()),
					joinErrors(this.insts.error().val(),this.parteElse.error().val()));
		}

		 
		protected ArrayList<Insts> cod_exp() {
			ArrayList<Insts> cod_ir_f = new ArrayList<Insts>();
			cod_ir_f.add(Insts.nuevaIIrf(this.parteElse.ir_f().val()));
			return concat(this.exp0.cod().val(),concat(cod_ir_f,
							concat(this.insts.cod().val(),this.parteElse.cod().val())));
		}

		 
		protected Integer etq_exp() {
			return new Integer(this.parteElse.etq().val());
		}
		private Exp0 exp0;
		private Instrucciones insts;
		private ParteElse parteElse;
	}
	

	public class InstruccionR4 extends Instruccion {
		public InstruccionR4(Token IDEN){
			super();
			this.IDEN=IDEN;
			
			//Dependencias
			error().ponDependencias(tsh());
			etq().ponDependencias(etqh(),tsh());
			cod().ponDependencias(tsh());
			
		}

		protected Error error_exp() {
			return escrituraCorrecta(this.tsh().val(),this.IDEN.leeLexema());
		}

		protected ArrayList<Insts> cod_exp() {
			return codigoEscritura(this.tsh().val(),this.IDEN.leeLexema());
		}

		protected Integer etq_exp() {
			return new Integer(this.etqh().val()+
					numeroInstruccionesEscritura(this.IDEN.leeLexema(),this.tsh().val()));
		}
		private Token IDEN;
	}

	public class ParametrosRealesR1 extends ParametrosReales {
		public ParametrosRealesR1(ListaParametrosReales listaParamReales){
			super();
			this.listaParamReales=listaParamReales;
			listaParamReales.registraCtx(new ListaParametrosRealesCtx() {
				
				public TS tsh_exp() {
					return ParametrosRealesR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer (ParametrosRealesR1.this.etqh().val()+
							numeroInstruccionesInicioLlamada());
				}
				
				public String subprogramah_exp() {
					return ParametrosRealesR1.this.subprogramah().val();
				}
				
			});
			
			//Dependencias
			listaParamReales.tsh().ponDependencias(tsh());
			listaParamReales.subprogramah().ponDependencias(subprogramah());
			listaParamReales.etqh().ponDependencias(etqh());
			
			error().ponDependencias(listaParamReales.error());
			nparams().ponDependencias(listaParamReales.nparams());
			etq().ponDependencias(listaParamReales.etq());
			cod().ponDependencias(listaParamReales.cod());
		}

		protected Error error_exp() {
			return this.listaParamReales.error().val();
		}

		protected ArrayList<Insts> cod_exp() {
			ArrayList<Insts> cod_desapila = new ArrayList<Insts>();
			cod_desapila.add(Insts.nuevaIDesapila());
			return concat(codigoInicioLlamada(),concat(this.listaParamReales.cod().val(),cod_desapila));
		}

		protected Integer etq_exp() {
			return new Integer(this.listaParamReales.etq().val()+1);
		}
		 
		private ListaParametrosReales listaParamReales;

		protected Integer nparams_exp() {
			return this.listaParamReales.nparams().val();
		}
	}

	public class ParametrosRealesR2 extends ParametrosReales {
		public ParametrosRealesR2(){
			super();
			
			//Dependencias
			etq().ponDependencias(etqh());
		}

		protected Error error_exp() {
		    return noError();
		    //return new Boolean (false);
		}

		protected ArrayList<Insts> cod_exp() {
			 return programaVacio();
		}

		protected Integer etq_exp() {
			 return this.etqh().val();
		}
		
		protected Integer nparams_exp() {
			 return new Integer(0);
		}
		
	}

	public class ListaParametrosRealesR1 extends ListaParametrosReales {
		public ListaParametrosRealesR1(ListaParametrosReales listaParamReales,Exp0 exp0){
			super();
			this.listaParamReales=listaParamReales;
			this.exp0=exp0;
			listaParamReales.registraCtx(new ListaParametrosRealesCtx() {
				
				public TS tsh_exp() {
					 return ListaParametrosRealesR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return new Integer(ListaParametrosRealesR1.this.etqh().val());
				}
				
				public String subprogramah_exp() {
					 return ListaParametrosRealesR1.this.subprogramah().val();
				}
			});
			exp0.registraCtx(new Exp0Ctx() {
				
				public TS tsh_exp() {
					 return ListaParametrosRealesR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return ListaParametrosRealesR1.this.listaParamReales.etq().val();
				}
			});
			
			//Dependencias
			listaParamReales.tsh().ponDependencias(tsh());
			listaParamReales.subprogramah().ponDependencias(subprogramah());
			listaParamReales.etqh().ponDependencias(etqh());
			
			exp0.tsh().ponDependencias(tsh());
			exp0.etqh().ponDependencias(listaParamReales.etq());
			
			error().ponDependencias(listaParamReales.error(),subprogramah(),listaParamReales.nparams(),exp0.tipo(),exp0.esDesignador(),tsh());
			nparams().ponDependencias(listaParamReales.nparams());
			etq().ponDependencias(exp0.etq());
			cod().ponDependencias(listaParamReales.cod(),exp0.cod(),subprogramah(),listaParamReales.nparams(),exp0.esDesignador(),tsh());
			
		}

		protected Error error_exp() {
			return joinErrors(this.listaParamReales.error().val(),
								parametroCorrecto(this.subprogramah().val(),this.listaParamReales.nparams().val()+1,
										this.exp0.tipo().val(),this.exp0.esDesignador().val(),this.tsh().val()));
		}

		protected ArrayList<Insts> cod_exp() {
			ArrayList<Insts> cod_copia = new ArrayList<Insts>();
			cod_copia.add(Insts.nuevaCopia());
			
			ArrayList<Insts> cod_apila = new ArrayList<Insts>();
			cod_apila.add(Insts.nuevaIApila(1));
			
			ArrayList<Insts> cod_suma = new ArrayList<Insts>();
			cod_suma.add(Insts.nuevaISuma());
			
			return concat(this.listaParamReales.cod().val(),concat(cod_copia,
					concat(cod_apila,concat(cod_suma,concat(this.exp0.cod().val(),codigoPaso(this.subprogramah().val(),
							this.listaParamReales.nparams().val(),this.exp0.esDesignador().val(),this.tsh().val()))))));
		}

		protected Integer etq_exp() {
			return new Integer(this.exp0.etq().val()+numeroInstruccionesCodigoPaso());
		}
		
		protected Integer nparams_exp() {
			return new Integer(this.listaParamReales.nparams().val()+1);
		}
		
		private ListaParametrosReales listaParamReales;
		private Exp0 exp0;
		
	}

	public class ListaParametrosRealesR2 extends ListaParametrosReales {

		public ListaParametrosRealesR2(Exp0 exp0){
			super();
			this.exp0=exp0;
			exp0.registraCtx(new Exp0Ctx() {
				
				public TS tsh_exp() {
					 return ListaParametrosRealesR2.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return new Integer(ListaParametrosRealesR2.this.etqh().val()+1);
				}
			});
			
			//Dependencia
			exp0.tsh().ponDependencias(tsh());
			exp0.etqh().ponDependencias(etqh());
			
			error().ponDependencias(subprogramah(),exp0.tipo(),exp0.esDesignador(),tsh());
			etq().ponDependencias(exp0.etq());
			cod().ponDependencias(exp0.cod(),subprogramah(),exp0.esDesignador(),tsh()); 
			
		}
		
		protected Error error_exp() {
			return parametroCorrecto(this.subprogramah().val(),1,this.exp0.tipo().val(),
					this.exp0.esDesignador().val(),this.tsh().val());
		}

		protected ArrayList<Insts> cod_exp() {
			ArrayList<Insts> cod_copia = new ArrayList<Insts>();
			cod_copia.add(Insts.nuevaCopia());
			
			
			return concat(cod_copia,concat(this.exp0.cod().val(),codigoPaso(this.subprogramah().val(),
					1,this.exp0.esDesignador().val(),this.tsh().val())));
		}

		protected Integer etq_exp() {
			return new Integer(this.exp0.etq().val()+numeroInstruccionesCodigoPaso());
		}
		
		protected Integer nparams_exp() {
			return new Integer(1);
		}
		
		private Exp0 exp0;
	}

	public class ParteElseR1 extends ParteElse {

		public ParteElseR1(Instrucciones insts){
			super();
			this.insts=insts;
			insts.registraCtx(new InstruccionesCtx() {
				public TS tsh_exp() {
					return ParteElseR1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer(ParteElseR1.this.etqh().val()+1);
					//return new Integer(ParteElseR1.this.etq().val()+1);
				}
			});
			
			//Dependencias
			insts.tsh().ponDependencias(tsh());
			insts.etqh().ponDependencias(etqh());
			//insts.etqh().ponDependencias(etq());
			
			error().ponDependencias(insts.error());
			etq().ponDependencias(insts.etq());
			cod().ponDependencias(insts.etq(),insts.cod());
			ir_f().ponDependencias(etqh());
			//ir_f().ponDependencias(etq());
			
			
			
		}
		
		protected Error error_exp() {
			return this.insts.error().val();
		}

		protected ArrayList<Insts> cod_exp() {
			ArrayList<Insts> cod_ira = new ArrayList<Insts>();
			cod_ira.add(Insts.nuevaIIra(this.insts.etq().val()));
			
			return concat(cod_ira,this.insts.cod().val());
		}

		protected Integer etq_exp() {
			return this.insts.etq().val();
		}
		
		protected Integer ir_f_exp() {
			return new Integer(this.etqh().val()+1);
			//return new Integer(this.etq().val()+1);
		}
	
		private Instrucciones insts;
	}
	

	public class ParteElseR2 extends ParteElse {

		public ParteElseR2(){
			super();
			
			//Dependencia
			etq().ponDependencias(etqh());
			ir_f().ponDependencias(etqh());
		}
		
		protected Error error_exp() {
			return noError();
		}

		protected ArrayList<Insts> cod_exp() {
			return programaVacio();
		}

		protected Integer etq_exp() {
			return this.etqh().val();
		}
		
		protected Integer ir_f_exp() {
			return this.etqh().val();
		}
	}

	public class Exp0R1 extends Exp0 {
		public Exp0R1(Exp1 exp1,OpComparacion opC,Exp1 exp1_1){
			super();
			this.exp1=exp1;
			this.exp1_1=exp1_1;
			this.opC = opC;
			exp1.registraCtx(new Exp1Ctx() {
				
				public TS tsh_exp() {
					 return Exp0R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return Exp0R1.this.etqh().val();
				}
			});
			exp1_1.registraCtx(new Exp1Ctx() {
				
				public TS tsh_exp() {
					 return Exp0R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return Exp0R1.this.exp1.etq().val() + unoSiCierto(Exp0R1.this.exp1.esDesignador().val()); 
				}
			});
				
			//Dependencia
			exp1.tsh().ponDependencias(tsh());
			exp1.etqh().ponDependencias(etqh());
			
			exp1_1.tsh().ponDependencias(tsh());
			exp1_1.etqh().ponDependencias(exp1.etq(),exp1.esDesignador());
			
			tipo().ponDependencias(opC.op(),exp1.tipo(),exp1_1.tipo());
			etq().ponDependencias(exp1_1.etq(),exp1_1.esDesignador());	 
			cod().ponDependencias(exp1.cod(),exp1_1.cod(),opC.cod(),exp1.esDesignador(),exp1_1.esDesignador());
		}

		protected ArrayList<Insts> cod_exp() {
			return codigoOpComparacion(this.exp1.cod().val(),this.exp1_1.cod().val(),
					                   this.opC.cod().val(),this.exp1.esDesignador().val(),
					                   this.exp1_1.esDesignador().val());
		}

		protected Integer etq_exp() {
			 return new Integer(this.exp1_1.etq().val()+unoSiCierto(this.exp1_1.esDesignador().val())+1);
		}

		protected Tipo tipo_exp() {
			return tipoOpBin(this.opC.op().val(),this.exp1.tipo().val(),this.exp1_1.tipo().val());
		}

		protected Boolean esDesignador_exp() {
			return new Boolean(false);
		}
		private Exp1 exp1;
		private Exp1 exp1_1;
		private OpComparacion opC;
	}

	public class Exp0R2 extends Exp0 {
		public Exp0R2(Exp1 exp1){
		   super();
		   this.exp1=exp1;
		   exp1.registraCtx(new Exp1Ctx() {
			
			public TS tsh_exp() {
				return Exp0R2.this.tsh().val();
			}
			
			public Integer etqh_exp() {
				return Exp0R2.this.etqh().val();
			}
		});
		   
		   //Dependencias
		   exp1.tsh().ponDependencias(tsh());
		   exp1.etqh().ponDependencias(etqh());
		   
		   tipo().ponDependencias(exp1.tipo());
		   esDesignador().ponDependencias(exp1.esDesignador());
		   etq().ponDependencias(exp1.etq());
		   cod().ponDependencias(exp1.cod());
		}

		protected ArrayList<Insts> cod_exp() {
			 return Exp0R2.this.exp1.cod().val();
		}

		protected Integer etq_exp() {
			return Exp0R2.this.exp1.etq().val();
		}

		protected Tipo tipo_exp() {
			return Exp0R2.this.exp1.tipo().val();
		}

		protected Boolean esDesignador_exp() {
			return Exp0R2.this.exp1.esDesignador().val();
		}
		private Exp1 exp1;
	}

	public class Exp1R1 extends Exp1 {
		public Exp1R1(Exp1 exp1,OpAditivo opA,Exp2 exp2){
			super();
			this.exp1=exp1;
			this.exp2=exp2;
			this.opA=opA;
			exp1.registraCtx(new Exp1Ctx() {
				
				public TS tsh_exp() {
					 return Exp1R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return Exp1R1.this.etqh().val();
				}
			});
			exp2.registraCtx(new Exp2Ctx() {
				
				public TS tsh_exp() {
					 return Exp1R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					 return new Integer (Exp1R1.this.exp1.etq().val() + 
							 unoSiCierto(Exp1R1.this.exp1.esDesignador().val()));
				}
			});
			
			//Dependencias
			exp1.tsh().ponDependencias(tsh());
			exp1.etqh().ponDependencias(etqh());
			
			exp2.tsh().ponDependencias(tsh());
			exp2.etqh().ponDependencias(exp1.etq(),exp1.esDesignador());
			
			tipo().ponDependencias(opA.op(),exp1.tipo(),exp2.tipo());
			etq().ponDependencias(exp2.etq(),exp2.esDesignador());	 
			cod().ponDependencias(exp1.cod(),exp2.cod(),opA.cod(),exp1.esDesignador(),exp2.esDesignador());
			
		}

		 
		protected ArrayList<Insts> cod_exp() {
			return codigoOpAditivo(this.exp1.cod().val(),this.exp2.cod().val(),
					this.opA.cod().val(),this.exp1.esDesignador().val(),
					this.exp2.esDesignador().val());
		}
		 
		protected Integer etq_exp() {
			return new Integer (this.exp2.etq().val()+unoSiCierto(this.exp2.esDesignador().val())+1);
		}

		 
		protected Tipo tipo_exp() {
			return tipoOpBin(this.opA.op().val(),this.exp1.tipo().val(),this.exp2.tipo().val());
		}

	 
		protected Boolean esDesignador_exp() {
			return new Boolean (false);
		}
		private Exp1 exp1;
		private Exp2 exp2;
		private OpAditivo opA;
		
	}

	public class Exp1R2 extends Exp1 {
		public Exp1R2(Exp2 exp2)
		{
			super();
			this.exp2=exp2;
			exp2.registraCtx(new Exp2Ctx() {
				
				public TS tsh_exp() {
					return Exp1R2.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer(Exp1R2.this.etqh().val());
				}
			});
			
			 //Dependencias
			   exp2.tsh().ponDependencias(tsh());
			   exp2.etqh().ponDependencias(etqh());
			   
			   tipo().ponDependencias(exp2.tipo());
			   esDesignador().ponDependencias(exp2.esDesignador());
			   etq().ponDependencias(exp2.etq());
			   cod().ponDependencias(exp2.cod());
		}

		protected ArrayList<Insts> cod_exp() {
			return this.exp2.cod().val();
		}

		protected Integer etq_exp() {
			return this.exp2.etq().val();
		}

		protected Tipo tipo_exp() {
			return this.exp2.tipo().val();
		}

		protected Boolean esDesignador_exp() {
			return new Boolean (this.exp2.esDesignador().val());
		}
		
		private Exp2 exp2;
	}

	public class Exp2R1 extends Exp2 {
		public Exp2R1(Exp2 exp2,OpMultiplicativo opM,Exp3 exp3){
			super();
			this.exp2=exp2;
			this.opM=opM;
			this.exp3=exp3;
			exp2.registraCtx(new Exp2Ctx() {
				
				public TS tsh_exp() {
					return Exp2R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return Exp2R1.this.etqh().val();
				}
			});
			exp3.registraCtx(new Exp3Ctx() {
				
				public TS tsh_exp() {
					return Exp2R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer(Exp2R1.this.exp2.etq().val()+
							unoSiCierto(Exp2R1.this.exp2.esDesignador().val()));
				}
			});
			
			//Dependencias
			exp2.tsh().ponDependencias(tsh());
			exp2.etqh().ponDependencias(etqh());
			
			exp3.tsh().ponDependencias(tsh());
			exp3.etqh().ponDependencias(exp2.etq(),exp2.esDesignador());
			
			tipo().ponDependencias(opM.op(),exp2.tipo(),exp3.tipo());
			etq().ponDependencias(exp3.etq(),exp3.esDesignador());	 
			cod().ponDependencias(exp2.cod(),exp3.cod(),opM.cod(),exp2.esDesignador(),exp3.esDesignador());
			
		}

		protected ArrayList<Insts> cod_exp() {
			return codigoOpMultiplicativo(this.exp2.cod().val(),
					this.exp3.cod().val(),this.opM.cod().val(),
					this.exp2.esDesignador().val(),this.exp3.esDesignador().val());
		}

		protected Integer etq_exp() {
			return new Integer(this.exp3.etq().val()+
					unoSiCierto(this.exp3.esDesignador().val())+1);
		}

		protected Tipo tipo_exp() {
			return tipoOpBin(this.opM.op().val(),this.exp2.tipo().val(),
					this.exp3.tipo().val());
		}

		protected Boolean esDesignador_exp() {
			return new Boolean(false);
		}
		
		private Exp2 exp2;
		private OpMultiplicativo opM;
		private Exp3 exp3;
		
	}

	public class Exp2R2 extends Exp2 {
		public Exp2R2(Exp3 exp3){
			super();
			this.exp3=exp3;
			exp3.registraCtx(new Exp3Ctx() {
				public TS tsh_exp() {
					return Exp2R2.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer(Exp2R2.this.etqh().val());
				}
			});
			
			 //Dependencias
			   exp3.tsh().ponDependencias(tsh());
			   exp3.etqh().ponDependencias(etqh());
			   
			   tipo().ponDependencias(exp3.tipo());
			   esDesignador().ponDependencias(exp3.esDesignador());
			   etq().ponDependencias(exp3.etq());
			   cod().ponDependencias(exp3.cod());
			
		}

		protected ArrayList<Insts> cod_exp() {
			return this.exp3.cod().val();
		}

		protected Integer etq_exp() {
			return new Integer(this.exp3.etq().val());
		}

		protected Tipo tipo_exp() {
			return this.exp3.tipo().val();
		}

		protected Boolean esDesignador_exp() {
			return this.exp3.esDesignador().val();
		}

		private Exp3 exp3;
	}

	public class Exp3R1 extends Exp3 {
		public Exp3R1(OpUnario opU,Exp3 exp3){
			super();
			this.opU=opU;
			this.exp3=exp3;
			exp3.registraCtx(new Exp3Ctx() {	
				public TS tsh_exp() {
					return Exp3R1.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer(Exp3R1.this.etqh().val());
				}
			});
			
			//Dependencias
			exp3.tsh().ponDependencias(tsh());
			exp3.etqh().ponDependencias(etqh());
			
			tipo().ponDependencias(opU.op(),exp3.tipo());
			etq().ponDependencias(exp3.etq(),exp3.esDesignador());	 
			cod().ponDependencias(exp3.cod(),opU.cod(),exp3.esDesignador());
			
		}

		protected ArrayList<Insts> cod_exp() {
			return codigoOpUnario(this.exp3.cod().val(),this.opU.cod().val(),
					this.exp3.esDesignador().val());
		}

		protected Integer etq_exp() {
			return new Integer(this.exp3.etq().val()+
					numeroDeInstruccionesOpUnario(this.exp3.esDesignador().val()));
		}

		protected Tipo tipo_exp() {
			return tipoOpUn(this.opU.op().val(),this.exp3.tipo().val());
		}

		protected Boolean esDesignador_exp() {
			return new Boolean(false);
		}
		
		private OpUnario opU;
		private Exp3 exp3;
	}

	public class Exp3R2 extends Exp3 {
		public Exp3R2(Exp4 exp4){
			super();
			this.exp4=exp4;
			exp4.registraCtx(new Exp4Ctx() {
				public TS tsh_exp() {
					return Exp3R2.this.tsh().val();
				}
				
				public Integer etqh_exp() {
					return new Integer(Exp3R2.this.etqh().val());
				}
			});
			
			 //Dependencias
			   exp4.tsh().ponDependencias(tsh());
			   exp4.etqh().ponDependencias(etqh());
			   
			   tipo().ponDependencias(exp4.tipo());
			   esDesignador().ponDependencias(exp4.esDesignador());
			   etq().ponDependencias(exp4.etq());
			   cod().ponDependencias(exp4.cod());
		}

		protected ArrayList<Insts> cod_exp() {
			return this.exp4.cod().val();
		}

		protected Integer etq_exp() {
			return new Integer(this.exp4.etq().val());
		}

		protected Tipo tipo_exp() {
			return this.exp4.tipo().val();
		}

		protected Boolean esDesignador_exp() {
			return this.exp4.esDesignador().val();
		}

		private Exp4 exp4;
	}

	public class Exp4R1 extends Exp4 {
		public Exp4R1(Token NUM){
			super();
			this.NUM=NUM;
			
			//Dependencia
			etq().ponDependencias(etqh());
		}

		protected ArrayList<Insts> cod_exp() {
			ArrayList<Insts> cod_apila = new ArrayList<Insts>();
			cod_apila.add(Insts.nuevaIApila(Integer.parseInt(NUM.leeLexema())));
			return cod_apila;
		}

		protected Integer etq_exp() {
			return new Integer(this.etqh().val()+1);
		}

		protected Tipo tipo_exp() {
			return new TipoNumerico();
		}

		protected Boolean esDesignador_exp() {
			return new Boolean(false);
		}
		
		private Token NUM;
	}

	public class Exp4R2 extends Exp4 {
		public Exp4R2(Token IDEN){
			super();
			this.IDEN=IDEN;
			
			//Dependencia
			tipo().ponDependencias(tsh());
			etq().ponDependencias(etqh(),tsh());
			cod().ponDependencias(tsh());
			
		}

		protected ArrayList<Insts> cod_exp() {
			return codigoAccesoVar(this.IDEN.leeLexema(),this.tsh().val());
		}

		protected Integer etq_exp() {
			return new Integer(this.etqh().val()+numeroInstruccionesAccesoVar(
					this.IDEN.leeLexema(),this.tsh().val()));
		}

		protected Tipo tipo_exp() {
			return tipoDe(this.IDEN.leeLexema(),this.tsh().val());
		}

		protected Boolean esDesignador_exp() {
			return new Boolean(true);
		}
		
		private Token IDEN;
	}

	public class Exp4R3 extends Exp4 {
		public Exp4R3(Exp0 exp0){
			super();
			this.exp0=exp0;
			exp0.registraCtx(new Exp0Ctx() {
				public TS tsh_exp() {
					return Exp4R3.this.tsh().val();
				}
				public Integer etqh_exp() {
					return Exp4R3.this.etqh().val();
				}
			});
			
			//Dependencia
			exp0.tsh().ponDependencias(tsh());
			exp0.etqh().ponDependencias(etqh());
			
			tipo().ponDependencias(exp0.tipo());
			esDesignador().ponDependencias(exp0.esDesignador());
			etq().ponDependencias(exp0.etq());
			cod().ponDependencias(exp0.cod());
		}

		protected ArrayList<Insts> cod_exp() {
			return this.exp0.cod().val();
		}

		protected Integer etq_exp() {
			return this.exp0.etq().val();
		}

		protected Tipo tipo_exp() {
			return this.exp0.tipo().val();
		}

		protected Boolean esDesignador_exp() {
			return this.exp0.esDesignador().val();
		}
		
		private Exp0 exp0;
	}

	public class OpComparacionR1 extends OpComparacion {
		public OpComparacionR1(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIEq());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.IGUAL;
		}
		
		private ArrayList<Insts> cod;
		
	}

	public class OpComparacionR2 extends OpComparacion {
		public OpComparacionR2(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaINeq());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.DISTINTO;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpComparacionR3 extends OpComparacion {
		public OpComparacionR3(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIMayor());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MAYOR;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpComparacionR4 extends OpComparacion {
		public OpComparacionR4(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIMayorIgual());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MAYORIGUAL;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpComparacionR5 extends OpComparacion {
		public OpComparacionR5(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIMenor());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MENOR;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpComparacionR6 extends OpComparacion {
		public OpComparacionR6(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIMenorIgual());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MENORIGUAL;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpAditivoR1 extends OpAditivo {
		public OpAditivoR1(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaISuma());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MAS;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpAditivoR2 extends OpAditivo {
		public OpAditivoR2(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIResta());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MENOS;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpAditivoR3 extends OpAditivo {
		public OpAditivoR3(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIOr());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.OR;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpMultiplicativoR1 extends OpMultiplicativo {
		public OpMultiplicativoR1(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIMul());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MULT;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpMultiplicativoR2 extends OpMultiplicativo {
		public OpMultiplicativoR2(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIDiv());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.DIV;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpMultiplicativoR3 extends OpMultiplicativo {
		public OpMultiplicativoR3(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIAnd());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.AND;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpUnarioR1 extends OpUnario {
		public OpUnarioR1(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaIMenos());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.MENOS;
		}
		
		private ArrayList<Insts> cod;
	}

	public class OpUnarioR2 extends OpUnario {
		public OpUnarioR2(){
			super();
		}

		protected ArrayList<Insts> cod_exp() {
			cod = new ArrayList<Insts>();
			cod.add(Insts.nuevaINot());
			return cod;
		}

		protected CatLexica op_exp() {
			return CatLexica.NOT;
		}
		
		private ArrayList<Insts> cod;
	}

	
	//FUNCIONES AUXILIARES
	
	public Error noError() {
		return new Error();
	}

	public Error joinErrors(Error e1, Error e2) {
		return new Error(e1, e2);
	}
	
	public ArrayList<Insts> concat(List<Insts> c1, List<Insts> c2) { 
		
		ArrayList<Insts> result = new ArrayList<Insts>(c1);
		result.addAll(c2);
		return result;
	}

	public ArrayList<Insts> concat(List<Insts> c1, Insts i) {
		ArrayList<Insts> result = new ArrayList<Insts>(c1);
		result.add(i);
		return result;
	}
	
	//FUNCIONES
	
	/*Añade un nuevo símbolo a la tabla de símbolos.
	Parámetro 1: La tabla de símbolos actual.
	Parámetro 2: El nombre del símbolo.
	Parámetro 3: La clase del símbolo.
	Parámetro 4: El tipo del símbolo.
	Parámetro 5: La dirección del símbolo.
	Parámetro 6: El nivel del bloque en el que el símbolo está declarado.
	Resultado: La tabla de símbolos que resulta de añadir el símbolo a la actual.
	*/
	
	public TS aniadeSimb(TS ts, String nombre, Clase clase, Tipo tipo, Integer dir, Integer nivel){
		ts.aniadeSimb(nombre, clase, tipo, dir, nivel);
		return ts;
	}
	
	/*Añade un elemento al final de una lista	--> ParametrosFormales
	Parámetro 1: La lista inicial
	Parámetro 2: El elemento
	Resultado: La lista resultante
	*/
	
	public List<Modo> aniadeA(List lista, Modo modo){
		lista.add(modo);
		return lista;
	}
	
	/*Comprueba las restricciones contextuales de la sentencia de asignación	
	Parámetro 1: La tabla de símbolos
	Parámetro 2: El identificador que está en la parte izquierda 
	Parámetro 3: El tipo de la parte derecha
	Resultado: Resultado de comprobar las restricciones
	*/

	public Error asignacionCorrecta(TS ts, String iden, Tipo tipo){
		
		Tipo t = tipoDe(iden, ts);
		if (t!=null){
			if ((t instanceof TipoNumerico) && (tipo instanceof TipoNumerico)){
				return noError();
			}
			else new Error("Asignacion incorrecta");
		}
		return new Error("Tipo es null");
	}
	
	/*Código necesario para obtener la dirección absoluta de una variable	
	Parámetro 1: Variable
	Parámetro 2: Tabla de símbolos
	Resultado: El código
	*/
	
	public ArrayList<Insts> codigoAccesoVar(String var, TS ts){
		Propiedad prop = ts.getPropiedades(var);
		ArrayList<Insts> cod = new ArrayList<Insts>(); 
		cod.add(Insts.nuevaIApilaDir(1+prop.getNivel()));
		cod.add(Insts.nuevaIApila(prop.getDir()));
		cod.add(Insts.nuevaISuma());
		if (prop.getClase().compareTo(Clase.pvar)==0){
			cod.add(Insts.nuevaIApilaInd());
		}
		return cod;
	}
	
	/*Devuelve la lista de instrucciones necesarias para activar el programa principal 
	Parámetro 1: Tamaño de los datos del programa principal
	Parámetro 2: Dirección de la primera instrucción del programa principal.
	Parámetro 3: Nivel máximo de anidamiento del programa
	Resultado: La citada lista de instrucciones
	*/
	
	public ArrayList<Insts> codigoActivacionProgramaPrincipal(Integer tamDatos, 
			Integer dirInicial, Integer nivelMax){
		ArrayList<Insts> cod = new ArrayList<Insts>(); 
		cod.add(Insts.nuevaIInicio(nivelMax, tamDatos));
	//	cod.add(Insts.nuevaIIra(dirInicial));
		return cod;
	}

	/*Instrucciones necesarias para llevar a cabo la asignación	
	Parámetro 1: La tabla de símbolos
	Parámetro 2:  El identificador que está en la parte izquierda 
	Parámetro 3: El código resultante de traducir la parte derecha
	Parámetro 4: Booleano que indica si la parte derecha es o no un designador
	Resultado: Código que implementa la asignación
	*/
	
	private int numInstAsignacion=0;
	public ArrayList<Insts> codigoAsignacion(TS ts, String iden, 
			ArrayList<Insts> cod_exp, boolean esDesignador){
		numInstAsignacion=0;
		ArrayList<Insts> cod = new ArrayList<Insts>();
		cod.addAll(codigoAccesoVar(iden, ts));
		numInstAsignacion+=cod.size();
		cod.addAll(cod_exp);
		numInstAsignacion+=cod_exp.size();
		if (esDesignador){
			cod.add(Insts.nuevaIApilaInd());
			numInstAsignacion+=1;
		}
		cod.add(Insts.nuevaIDesapilaInd());
		numInstAsignacion+=1;
		return cod; 
	}

	/*Devuelve la lista de instrucciones correspondientes al epílogo de un procedimiento.	
	Parámetro 1: Tamaño de los datos locales del procedimiento.
	Parámetro 2: Nivel de anidamiento del procedimiento.
	Resultado: La citada lista de instrucciones
	*/
	
	public ArrayList<Insts> codigoEpilogo(Integer tam, Integer nivel){
		ArrayList<Insts> cod = new ArrayList<Insts>(); 
		//Actualizar CP
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(tam+2));
		cod.add(Insts.nuevaIResta());
		cod.add(Insts.nuevaIDesapilaDir(0));
		//Restaurar display
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(2));
		cod.add(Insts.nuevaISuma());
		cod.add(Insts.nuevaIApilaInd());
		cod.add(Insts.nuevaIDesapilaDir(nivel+1)); //TODO No se si es nivel+1 porque le suma 1 al pasar el parametro
		// Apilar dir ret
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(1));
		cod.add(Insts.nuevaISuma());
		cod.add(Insts.nuevaIApilaInd());
		//Ir a ret
		cod.add(Insts.nuevaIIrInd());
		return cod;
	}
	
	/*Instrucciones necesarias para escribir el valor de una variable	
	Parámetro 1: La tabla de símbolos
	Parámetro 2: La variable a escribir
	Resultado: Lista de instrucciones para realizar la escritura
	*/
	
	public ArrayList<Insts> codigoEscritura(TS ts, String iden){
		ArrayList<Insts> cod = new ArrayList<Insts>(); 
		cod.addAll(codigoAccesoVar(iden, ts));
		cod.add(Insts.nuevaIEscritura());
		return cod;
	}
	
	/*Instrucciones necesarias para realizar la llamada a un procedimiento (una vez pasados todos los parámetros)	
	Parámetro 1: Nombre del procedimiento
	Parámetro 2: Tabla de símbolos
	Parámetro 3: Dirección de retorno
	Resultado: Instrucciones para realizar la llamada
	*/
	
	public ArrayList<Insts> codigoFinLlamada(String iden, TS ts, Integer dirRetorno){
		//Se hace en el epilogo
		return new ArrayList<Insts>();
	}
	
	/*Instrucciones necesarias para iniciar el paso de parámetros	
	Resultado: Instrucciones necesarias para iniciar el paso de parámetros.
	*/
	
	public ArrayList<Insts> codigoInicioLlamada(){
		ArrayList<Insts> cod = new ArrayList<Insts>();
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(3));
		cod.add(Insts.nuevaISuma());
		return cod;
	}
	
	/*Código necesario para implementar una operación aditiva	
	Parámetro 1: Código del primer operando
	Parámetro 2: Código del segundo operando
	Parámetro 3: Código del Operador
	Parámetro 4: ¿Es el primer operando un designador?
	Parámetro 5: ¿Es el segundo operando un designador?
	Resultado: El código
	*/
	
	public ArrayList<Insts> codigoOpAditivo(ArrayList<Insts> cod_op1, 
			ArrayList<Insts> cod_op2, ArrayList<Insts> cod_op, 
			boolean esDesignador1, boolean esDesignador2){
		ArrayList<Insts> cod = new ArrayList<Insts>();
		cod.addAll(cod_op1);
		if (esDesignador1){
			cod.add(Insts.nuevaIApilaInd());
		}
		cod.addAll(cod_op2);
		if (esDesignador2){
			cod.add(Insts.nuevaIApilaInd());
		}
		cod.addAll(cod_op);
        return cod;
	}
	
	/*Código necesario para implementar una operación de comparacion	
	Parámetro 1: Código del primer operando
	Parámetro 2: Código del segundo operando
	Parámetro 3: Código del Operador
	Parámetro 4: ¿Es el primer operando un designador?
	Parámetro 5: ¿Es el segundo operando un designador?
	Resultado: El código
	*/
	
	public ArrayList<Insts> codigoOpComparacion(ArrayList<Insts> cod_op1, 
			ArrayList<Insts> cod_op2, ArrayList<Insts> cod_op, 
			boolean esDesignador1, boolean esDesignador2){
		ArrayList<Insts> cod = new ArrayList<Insts>();
		cod.addAll(cod_op1);
		if (esDesignador1){
			cod.add(Insts.nuevaIApilaInd());
		}
		cod.addAll(cod_op2);
		if (esDesignador2){
			cod.add(Insts.nuevaIApilaInd());
		}
		cod.addAll(cod_op);
        return cod;
	}
	
	/*Código necesario para implementar una operación multiplicativa	
	Parámetro 1: Código del primer operando
	Parámetro 2: Código del segundo operando
	Parámetro 3: Código del Operador
	Parámetro 4: ¿Es el primer operando un designador?
	Parámetro 5: ¿Es el segundo operando un designador?
	Resultado: El código*/
	
	public ArrayList<Insts> codigoOpMultiplicativo(ArrayList<Insts> cod_op1, 
			ArrayList<Insts> cod_op2, ArrayList<Insts> cod_op, 
			boolean esDesignador1, boolean esDesignador2){
		ArrayList<Insts> cod = new ArrayList<Insts>();
		cod.addAll(cod_op1);
		if (esDesignador1){
			cod.add(Insts.nuevaIApilaInd());
		}
		cod.addAll(cod_op2);
		if (esDesignador2){
			cod.add(Insts.nuevaIApilaInd());
		}
		cod.addAll(cod_op);
        return cod;
	}
	
	/*Código necesario para implementar una operación unaria	
	Parámetro 1: Código del operando
	Parámetro 2: Código del Operador
	Parámetro 3: ¿Es el operando un designador?
	Resultado: El código
	*/
	
	private int numInstOpUnario=0;
	
	public ArrayList<Insts> codigoOpUnario(ArrayList<Insts> cod_operando, 
			ArrayList<Insts> cod_operador, boolean esDesignador){
		numInstOpUnario=0;
		ArrayList<Insts> cod = new ArrayList<Insts>();
		cod.addAll(cod_operando);
		numInstOpUnario=numInstOpUnario+cod_operando.size();
		if (esDesignador){
			cod.add(Insts.nuevaIApilaInd());
			numInstOpUnario=numInstOpUnario+1;
		}
		cod.addAll(cod_operador);
		numInstOpUnario=numInstOpUnario+cod_operador.size();
        return cod;
	}
	
	/*Instrucciones necesarias para realizar el paso del parámetro	
	Parámetro 1: Nombre del subprograma
	Parámetro 2: Número del parámetro real
	Parámetro 3: Booleano que indica si el parámetro real es o no un designador.
	Parámetro 4: Tabla de símbolos
	Resultado: Instrucciones que realizan el paso del parámetro.
	*/
	
	private int numInstPasoParametro = 0;
	
	public ArrayList<Insts> codigoPaso(String subprograma, 
			Integer nparam, boolean esdesignador, TS ts){
		numInstPasoParametro = 0;
		ArrayList<Insts> lcod = new ArrayList<Insts>();
		Propiedad prop = ts.getPropiedades(subprograma);
		Tipo tipo = prop.getTipo();
		for (int i=0; i<nparam; i++){
			Modo modo = tipo.getParams().get(i);
			int nivel = prop.getNivel();
			if (modo==Modo.valor){
				Insts copia = Insts.nuevaCopia();
				lcod.add(copia);
				Insts apila_dir = Insts.nuevaIApilaDir(nivel);
				lcod.add(apila_dir);
				Insts apila = Insts.nuevaIApila(0);
				lcod.add(apila);
				Insts suma = Insts.nuevaISuma();
				lcod.add(suma);
				Insts mueve = Insts.nuevaIMueve();
				lcod.add(mueve);
				numInstPasoParametro+=5;
			}
			else if (modo == Modo.var){
				Insts copia = Insts.nuevaCopia();
				lcod.add(copia);
				Insts apila = Insts.nuevaIApila(1);
				lcod.add(apila);
				Insts apila_dir = Insts.nuevaIApilaDir(nivel);
				lcod.add(apila_dir);
				Insts apila2 = Insts.nuevaIApila(0);
				lcod.add(apila2);
				Insts suma = Insts.nuevaISuma();
				lcod.add(suma);
				Insts desapilaind = Insts.nuevaIDesapilaInd();
				lcod.add(desapilaind);
				numInstPasoParametro+=6;
			}
			// a lo mejor falta un desapila
		}
		return lcod;
	}
	
	/*Devuelve la lista de instrucciones correspondientes al prólogo de un procedimiento.	
	Parámetro 1: Tamaño de los datos locales del procedimiento.
	Parámetro 2: Nivel de anidamiento del procedimiento.
	Resultado: La citada lista de instrucciones
	*/
	
	public ArrayList<Insts> codigoPrologo(Integer tamDatos, Integer nivel){
		ArrayList<Insts> cod = new ArrayList<Insts>();
		// Salvar display
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(2));
		cod.add(Insts.nuevaISuma());
		cod.add(Insts.nuevaIApilaDir(1+nivel));
		cod.add(Insts.nuevaIDesapilaInd());
		// Fijar valor display
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(3));
		cod.add(Insts.nuevaISuma());
		cod.add(Insts.nuevaIDesapilaDir(nivel+1)); //TODO No se si es nivel+1 porque le suma 1 al pasar el parametro
		// Espacio reservado
		cod.add(Insts.nuevaIApilaDir(0));
		cod.add(Insts.nuevaIApila(tamDatos+2));
		cod.add(Insts.nuevaISuma());
		cod.add(Insts.nuevaIDesapilaDir(0));
		return cod;
	}
	
	/*Determina si la condición de un if es o no del tipo correcto	
	Parámetro 1: Tipo de la condición
	Resultado: Resultado de comprobar la restricción.
	*/
	
	public Error condicionCorrecta(Tipo tipo){
		//TODO
		return noError();
	}
	
	/*Abre un nuevo nivel en la tabla de símbolos, que se corresponde con el ámbito de un nuevo bloque	
	Parámetro 1: La tabla de símbolos actual
	Resultado: La tabla de símbolos resultante
	*/
	
	public TS creaNivel(TS ts){
		ts.creaNivel();
		return ts;
	}
	
	/*Crea una nueva tabla de símbolos.	
	Resultado: La tabla de símbolos creada
	*/
	
	public TS creaTS(){
		return new TS();
	}
	
	/*Comprueba las restricciones contextuales de una sentencia de escritura	
	Parámetro 1: La tabla de símbolos
	Parámetro 2: La variable a escribir
	Resultado: Resultado de comprobar las restricciones.
	*/
	
	public Error escrituraCorrecta(TS ts, String var){
		//TODO
		return noError();
	}
	
	/*Determina si el nivel más actual de la tabla de símbolos (el último nivel creado en la tabla) 	
	Parámetro 1: La tabla de símbolos.
	Parámetro 2: El identificador.
	Resultado: Un valor booleano que indica si el símbolo está ya declarado o no en el nivel actualmente en vigencia.
	*/
	
	public Error existeSimbEnUltimoNivel(TS ts, String iden){ //Error o boolean??
		if (ts.existeSimbUlt(iden)) {
			return noError();
		}
		else return new Error("No existe el simbolo "+ iden +" en ultimo nivel");
	}
	
	/*Comprueba restricciones contextuales asociadas a la llamada de un procedimiento (¿existe el procedimiento?, ¿el número de parámetros reales es el correcto?) 	
	Parámetro 1: La tabla de símbolos
	Parámetro 2: El nombre del procedimiento
	Parámetro 3: Número de parámetros reales
	Resultado: Resultado de comprobar las restricciones
	*/
	
	public Error llamadaCorrecta(TS ts, String nombre, Integer nparams){
		//TODO
		return noError();
	}
	
	/*Construye una lista formada por un elemento	
	Parámetro 1: El elemento
	Resultado: La lista formada únicamente por el elemento dado
	*/
	
	public List<Modo> nuevaLista(Modo param){
		List<Modo> lista = new ArrayList<Modo>();
		lista.add(param);
		return lista;
	}
	
	/*Número de instrucciones necesarias para implementar una operación unaria	
	Parámetro 1: ¿Es el operando un designador?
	Resultado: El número
	*/
	
	public Integer numeroDeInstruccionesOpUnario(boolean esDesignador){
		//TODO no se si se actualiza correctamente
		return numInstOpUnario;
	}
	
	/*Número de instrucciones necesarias para obtener la dirección absoluta de una variable	
	Parámetro 1: Variable
	Parámetro 2: Tabla de símbolos
	Resultado: Número de instrucciones
	*/
	private int numInstAccesoVar=0;
	public Integer numeroInstruccionesAccesoVar(String var, TS ts){
		Clase c = ts.getPropiedades(var).getClase();
		if (c.compareTo(Clase.pvar)==0) numInstAccesoVar= 4;
		else numInstAccesoVar=3;
		return numInstAccesoVar;
	}
	
	/*Devuelve el número de instrucciones necesarias para activar el programa principal. 	
	Resultado: El número de instrucciones devueltas por codigoActivacionProgramaPrincipal
	*/
	
	
	public Integer numeroInstruccionesActivacionProgramaPrincipal(){
		return 2;
	}
	
	/*Número de instrucciones necesario para llevar a cabo la asignación	
	Parámetro 1: Variable en la parte izquierda
	Parámetro 2: Tabla de símbolos
	Resultado: Número de instrucciones devueltas por codigoAsignacion
	*/
	
	public Integer numeroInstruccionesAsignacion(String var, TS ts, Boolean esDesignador){
		return numInstAsignacion;
	}
	
	/*Número de instrucciones necesarias para realizar el paso del parámetro	
	Resultado: Número de instrucciones devueltas por codigoPaso
	*/
	
	public Integer numeroInstruccionesCodigoPaso(){
		return numInstPasoParametro;
	}
	
	/*Devuelve la lista de instrucciones del prólogo de los bloques	
	Resultado: El número de instrucciones devueltas por codigoEpilogo
	*/
	
	public Integer numeroInstruccionesEpilogo(){
		return 14;
	}
	
	/*Número de instrucciones necesarias para escribir el valor de una variable	
	Parámetro 1: Variable a escribir
	Parámetro 2: Tabla de símbolos
	Resultado: Número de instrucciones devueltas por codigoEscritura
	*/
	
	public Integer numeroInstruccionesEscritura(String var, TS ts){
		return 1+numInstAccesoVar;
	}
	
	/*Número de instrucciones necesarias para realizar la llamada a un procedimiento (una vez pasados todos los parámetros)	
	Resultado: Número de instrucciones devueltas por codigoFinLlamada
	*/
	
	public Integer numeroInstruccionesFinLlamada(){
		return 0;
	}
	
	/*Número de instrucciones necesarias para iniciar el paso de parámetros	
	Parámetro 1: Variable en la parte izquierda
	Parámetro 2: Tabla de símbolos
	Resultado: Número de instrucciones devueltas por codigoInicioLlamada
	*/
	
	public Integer numeroInstruccionesInicioLlamada(/*String var, TS ts*/){
		return 3;
	}
	
	/*Devuelve la lista de instrucciones del prólogo de los bloques	
	Resultado: El número de instrucciones devueltas por codigoPrologo
	*/
	
	public Integer numeroInstruccionesPrologo(){
		return 13;
	}
	
	/*Comprueba las restricciones contextuales del paso de un parámetro	
	Parámetro 1: Nombre del subprograma
	Parámetro 2: Número del parámetro real
	Parámetro 3: Tipo del parámetro real
	Parámetro 4: Booleano que indica si el parámetro real es o no un designador.
	Parámetro 5: Tabla de símbolos
	Resultado: Resultado de comprobar las restricciones.
	*/
	
	public Error parametroCorrecto(String nombre, Integer nparam, Tipo tipo, boolean esDesignador,
			TS ts){
		//TODO
		return noError();
	}
	
	/*Secuencia vacía de instrucciones	
	Resultado: La secuencia vacía de instrucciones
	*/
	
	public ArrayList<Insts> programaVacio(){
		return new ArrayList<Insts>();
	}
	
	/*El tipo de una expresión que involucra un operador binario	
	Parámetro 1: El operador
	Parámetro 2: Tipo del primer operando
	Parámetro 3: Tipo del segundo operando
	Resultado: El tipo de la operación
	*/
	
	public Tipo tipoOpBin(CatLexica op, Tipo top1, Tipo top2){
		if ((top1 instanceof TipoNumerico) && (top2 instanceof TipoNumerico)){
		return new TipoNumerico();
		}
		return null;
	}
	
	/*El tipo de una expresión que involucra un operador unario	
	Parámetro 1: El operador
	Parámetro 2: Tipo del operando
	Resultado: El tipo de la operación
	*/
	
	public Tipo tipoOpUn(CatLexica op, Tipo top){
		if (top instanceof TipoNumerico){
			return new TipoNumerico();
		}
		return null;
	}
	
	public Tipo tipoDe(String iden, TS ts){
		return ts.tipoDe(iden);
	}
	
	/*1 si su argumento es true, 0 en otro caso	
	Parámetro 1: Argumento
	Resultado: Valor
	*/
	
	public Integer unoSiCierto(boolean argumento) {
		if (argumento) {
			return new Integer(1);
		} else {
			return new Integer(0);
		}
	}

}
